package com.onion.orm.support.builder;

import java.util.List;

import com.alibaba.fastjson.JSON;
import com.onion.utils.utils.StringHelper;
import com.onion.core.entity.Enhanced;
import com.onion.orm.dao.DaoBuilder;
import com.onion.orm.dao.mybatis.MybatisEnhancedDao;
import com.onion.core.entity.EnhancedType;
import com.onion.orm.config.EnhancedConfig;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;

import io.github.lukehutch.fastclasspathscanner.scanner.AnnotationInfo;
import io.github.lukehutch.fastclasspathscanner.scanner.ClassInfo;
import io.github.lukehutch.fastclasspathscanner.scanner.AnnotationInfo.AnnotationParamValue;

/**
 * EnhancedDao构造器
 */
public class EnhancedDaoBuilder implements DaoBuilder {

    private Logger logger = LoggerFactory.getLogger(EnhancedDaoBuilder.class);

	@Override
	public EnhancedType getType() {
		return EnhancedType.ENHANCED;
	}

	@Override
	public BeanWrapper build(BuildContext buildContext) {
        BeanDefinitionBuilder daoBuilder = BeanDefinitionBuilder.genericBeanDefinition(MybatisEnhancedDao.class);

        ClassInfo classInfo = buildContext.getClazzInfo();
        List<AnnotationInfo> clazzAnnotations = classInfo.getAnnotationInfo();
        String daoBeanName = null;
        String tableName = null;
        
        for (AnnotationInfo annotationInfo : clazzAnnotations) {
            if (annotationInfo.getAnnotationType().isAssignableFrom(Enhanced.class)) {
                List<AnnotationParamValue> values = annotationInfo.getAnnotationParamValues();
                if (values != null && values.size() > 0) {
                    for (AnnotationParamValue annotationParamValue : values) {
                        String name = annotationParamValue.getParamName();
                        if (name.equals("name")) {
                            daoBeanName = (String) annotationParamValue.getParamValue();
                        } else if (name.equals("table")) {
                            tableName = (String) annotationParamValue.getParamValue();
                        }
                    }
                }
            }
        }

        //获取Dao名称
        if (StringUtils.isBlank(daoBeanName)) {
            String simpleName = EnhancedConfig.CLASS_NAME_PATTERN.matcher(classInfo.getClassName()).replaceAll("$1");
            StringBuilder beanNameBuilder = new StringBuilder();
            if (StringUtils.isNotEmpty(buildContext.getConfig().getPrefix())) {
                beanNameBuilder.append(buildContext.getConfig().getPrefix());
            }
            beanNameBuilder.append(StringHelper.toCamel(simpleName)).append(buildContext.getConfig().getPostfix());
            daoBeanName = beanNameBuilder.toString();
        }

        //设置构造函数参数
        daoBuilder.addConstructorArgValue(classInfo.getClassName());
        daoBuilder.addConstructorArgValue(tableName);
        daoBuilder.addConstructorArgReference(buildContext.getConfig().getSqlSessionFactory());

        if(StringUtils.isBlank(tableName)){
            logger.warn("创建EnhancedDao Bean实例异常: tableName为空, entity={}, annotations={}",
                        classInfo.getClassName(), JSON.toJSONString(clazzAnnotations));
        }

        return BeanWrapper.instance(daoBeanName, daoBuilder.getBeanDefinition());
	}

}